package ac2.util.serial.packets;

import ac2.Global;
import net.tinyos.util.Dump;

public abstract class AC2Packet implements IBytePacket {

	protected byte[] packet = new byte[14];

	protected byte targetNode = 0;
	protected byte messageId = 0;
	protected byte senderNode = 0;
	
	/**
	 * Create a blank AC2 packet with the target node and message Id.
	 * @param targetNode
	 * @param messageId
	 */
	public AC2Packet(byte targetNode, byte messageId)
	{
		this.targetNode = targetNode;
		this.messageId = messageId;
	}
	
	public byte getTargetNode() { return targetNode; }
	public byte getMessageId() { return messageId; }
	public byte getSenderNode() { return senderNode; }
	
	/**
	 * Creates an AC2Packet from the specified packet
	 * @param packet
	 * @throws Exception If the packet length does not match the expected length
	 */
	public AC2Packet(byte[] packet) throws Exception
	{
		Global.Debug("AC2Packet constructor");
		if (packet.length == this.packet.length)
		{
			// Copy the packet
			for (int i = 0; i < this.packet.length; i++)
			{
				this.packet[i] = packet[i];
			}
		}
		else
		{
			throw new Exception("Packet length is not the required length (" + this.packet.length + " bytes)");
		}
		
		parseHeader();
	}
	
	public void init()
	{
		parseBody();
	}
	
	protected void parseHeader()
	{
		Global.Debug("AC2Packet.parseHeader");
		// Ignore the first 8 bytes...just the zigbee header
		senderNode = packet[8];
		targetNode = packet[9];
		messageId = packet[10];
	}
	
	protected abstract void parseBody();
	
	/**
	 * Get the byte array from the packet
	 */
	public byte[] getBytes() {
		Global.Debug("AC2Packet.getBytes");
		
		// Populate the ZigBee header
		packet[0] = 0x00;
		packet[1] = 0x00;
		packet[2] = (byte) 0xF1;
		packet[3] = 0x00;
		packet[4] = 0x00;
		packet[5] = 0x06;
		packet[6] = 0x00;
		packet[7] = (byte) 0xF1;
		
		fillHeader(packet, 8, 3);
		fillBody(packet, 11, 3);

		
		return packet;
	}
	
	protected void fillHeader(byte[] packet, int start, int length) {
		Global.Debug("AC2Packet.fillHeader");
		
		packet[start++] = senderNode;	// Sender
		packet[start++] = targetNode;	// Receiver
		packet[start++] = messageId;	// Message ID for update temperature

	}
	
	
	protected abstract void fillBody(byte[] packet, int start, int length);

}
